﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace WooCoo.DataPortal.Server.Hosts.WcfChannel
{
    [DataContract(Namespace = "http://www.woocoo.com/")]
    public class ServiceExceptionDetail : ExceptionDetail
    {
        public const string FaultSubCodeNamespace = @"http://www.woocoo.com/exceptionhandling/";
        public const string FaultSubCodeName = "ServiceError";
        public const string FaultAction = @"http://www.w3.org/2005/08/addressing/soap/fault";

        [DataMember]
        public string AssemblyQualifiedName { get; private set; }

        [DataMember]
        public new ServiceExceptionDetail InnerException { get; private set; }

        public ServiceExceptionDetail(System.Exception ex)
            : base(ex)
        {
            this.AssemblyQualifiedName = ex.GetType().AssemblyQualifiedName;
            if (null != ex.InnerException)
            {
                this.InnerException = new ServiceExceptionDetail(ex.InnerException);
            }
        }

        public override string ToString()
        {
            return this.Message;
        }

        /// <summary>
        /// 通过反射,得到服务器具体的异常实例
        /// </summary>
        /// <param name="exceptionDetail"></param>
        /// <returns></returns>
        public static System.Exception GetException(ServiceExceptionDetail exceptionDetail)
        {
            if (null == exceptionDetail.InnerException)
            {
                try
                {
                    return (System.Exception)Activator.CreateInstance(System.Type.GetType(exceptionDetail.AssemblyQualifiedName), exceptionDetail.Message);
                }
                catch
                {
                    return new System.Exception("远程异常类型:" + exceptionDetail.AssemblyQualifiedName + System.Environment.NewLine
                        + "异常信息:" + exceptionDetail.Message + System.Environment.NewLine
                        + "异常跟踪:" + exceptionDetail.StackTrace
                        );
                }
            }

            System.Exception innerException = GetException(exceptionDetail.InnerException);

            try
            {
                return (System.Exception)Activator.CreateInstance(System.Type.GetType(exceptionDetail.AssemblyQualifiedName), exceptionDetail.Message, innerException);
            }
            catch (System.Exception)
            {
                return new System.Exception("远程错误信息:", innerException);
            }
        }
    }
}
